package com.dd.cloud.auth.security;

import com.dd.cloud.common.enums.ZkExceptionEnum;
import com.dd.cloud.common.exception.ZekeException;
import com.dd.cloud.common.utils.JsonUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.HttpStatus;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;

/**
 * <p>
 * 未授权的统一处理方式
 * </p>
 *
 * @author qy
 * @since 2019-11-08
 */
@Slf4j
public class UnauthorizedEntryPoint implements AuthenticationEntryPoint {

    @Override
    public void commence(HttpServletRequest request, HttpServletResponse res,
                         AuthenticationException authException) throws IOException, ServletException {
        /**
         * 未授权, 两种逻辑,
         * 1,请求不是到auth服务,只用此服务授权, 此时是网关调用, 授权失败返回false授权失败给网关
         * 2,请求就是到auth服务器, 此时是网关转发, 授权失败要返回异常码和异常信息给客户端,
         * 由于serurity是过滤器链,此时还在过滤器的调用流程中,无法用统一异常拦截,自定义异常返回
         */
        String error = (String) request.getAttribute("error");
        String msg = StringUtils.isBlank(error)?ZkExceptionEnum.NO_ERMSSION.getMsg():error;
        res.setStatus(HttpStatus.OK.value());
        res.setCharacterEncoding("UTF-8");
        res.setContentType("application/json;charset=utf-8");
        PrintWriter writer = null;
        if (StringUtils.isBlank(request.getParameter("uri"))) {
            Map<String, String> map = new HashMap<>();
            map.put("status", String.valueOf(ZkExceptionEnum.NO_ERMSSION.getCode()));
            map.put("message", msg);
            res.setStatus(ZkExceptionEnum.NO_ERMSSION.getCode());
            try {
                writer = res.getWriter();
                writer.print(JsonUtils.objectToStr(map));
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (writer != null) {
                    writer.close();
                }
            }
        } else {

            try {
                Map<String, String> map = new HashMap<>();
                map.put("status", String.valueOf(ZkExceptionEnum.NO_ERMSSION.getCode()));
                map.put("message", msg);
                writer = res.getWriter();
                writer.print(JsonUtils.objectToStr(map));
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (writer != null) {
                    writer.close();
                }
            }
        }
    }
}
